/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DataStructuresThreads;

import Sorting.Main;
import Sorting.ThreadAuxiliary;
import com.sun.j3d.utils.geometry.Box;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.*;
import javax.vecmath.Vector3f;

/**
 *
 * @author rafael
 */
public class StackThread extends Thread {
    
    private StackThread stackThread = this;
    public static boolean isRunning = false;
    public static Vector3f elementPosition = new Vector3f(-0.0f, -0.6f, -0.2f);

    public StackThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        execute();
    }

    private void execute() {

        try {
//            Main.textPane.setText(Main.textoStack);
            callStackButtons();
            Main.frame.setEnabled(false);

            BranchGroup bgroup = Main.stackBranchGroup();
            Main.textPane2.setText("tamanho = " + 0 + "\ncapacidade = " + (Main.vetorNumeros.length - 1));
            Main.su.addBranchGraph(bgroup);

        } finally {
            Main.isRunning = false;
            Main.textPane.setText(Main.textoStack);
        }
    }

    private static void checkElementPosition() {
        elementPosition.y = (Main.stackSize * 0.3f) - 0.6f;
    }

    public static void sleep(long sleepTime) {

        try {
            Thread.sleep(sleepTime);

        } catch (InterruptedException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void highlightsText(String string, String code) {
        Main.textPane.getStyledDocument().setCharacterAttributes(0, code.length(), Main.defaultText, true);
        int i = code.indexOf(string);
        Main.textPane.getStyledDocument().setCharacterAttributes(i, string.length(), Main.highlightedText, true);
        sleep(40 * 30);
    }

    public static void pushElement() {

        highlightsText("  se (tamanho == capacidade) {\n", Main.textoStack);
        if (Main.stackSize == Main.stackCapacity) {
            highlightsText("    Erro: Não há capacidade para mais elementos!\n", Main.textoStack);
            JOptionPane.showMessageDialog(null, "Capacidade está no limite, não pode adicionar novos elementos.");
            Main.textPane.getStyledDocument().setCharacterAttributes(0, Main.textoStack.length(), Main.defaultText, true);
        } else {
            highlightsText("  } senao {\n", Main.textoStack);

            String numberString = "";
            int number = -1;

            while (number < 0 || number > 9) {
                numberString = JOptionPane.showInputDialog("Qual o número à ser adicionado?");

                if (numberString == null || numberString.equals("")) {
                } else {
                    number = Integer.parseInt(numberString);
                }

            }

            BranchGroup branchGroup = new BranchGroup();

            Box stackElement = new Box(0.3f, 0.12f, 0.3f, Main.criarApp());
            stackElement.setCapability(Box.ENABLE_APPEARANCE_MODIFY);

            Transform3D tfBox = new Transform3D();

            checkElementPosition();

            tfBox.setTranslation(new Vector3f(elementPosition.x, elementPosition.y, elementPosition.z));

            TransformGroup tgBox = new TransformGroup(tfBox);
            tgBox.addChild(stackElement);
            branchGroup.addChild(tgBox);

            highlightsText("    pilha[tamanho] = numero;\n", Main.textoStack);
            Main.vetorNumeros[Main.stackSize] = new Sorting.Number(number, tgBox, 0);
            
            Main.su.addBranchGraph(branchGroup);
            
            highlightsText("    tamanho++;\n", Main.textoStack);
            Main.stackSize++;
            
            Main.textPane.getStyledDocument().setCharacterAttributes(0, Main.textoStack.length(), Main.defaultText, true);
            Main.textPane2.setText("tamanho = " + Main.stackSize + "\ncapacidade = " + (Main.capacity));
        }
    }

    public static void popElement() {

        Main.highlightsText("  se(tamanho == 0) {\n", Main.textoStack);
        if (Main.stackSize == 0) {
            Main.highlightsText("    Erro: Não há elementos à serem retirados!\n", Main.textoStack);
            JOptionPane.showMessageDialog(null, "Pilha vazia, não há elementos à serem retirados!");
            Main.textPane.getStyledDocument().setCharacterAttributes(0, Main.textoStack.length(), Main.defaultText, true);

        } else {
            Main.highlightsText("  } senao  {\n", Main.textoStack);

            Main.highlightsText("    pilha[tamanho - 1] = null;\n", Main.textoStack);
            Main.destroySphereGeneric(Main.vetorNumeros, Main.stackSize - 1);
            Main.vetorNumeros[Main.stackSize - 1] = null;
            Main.highlightsText("    tamanho--;\n", Main.textoStack);
            Main.stackSize--;
            Main.textPane.getStyledDocument().setCharacterAttributes(0, Main.textoStack.length(), Main.defaultText, true);
            Main.textPane2.setText("tamanho = " + Main.stackSize + "\ncapacidade = " + (Main.capacity));
        }

    }

    public static void topElement() {

        Main.highlightsText("  se (tamanho == 0) {\n", Main.textoStack);
        if (Main.stackSize == 0) {
            Main.highlightsText("    Erro: Não há elementos na pilha!\n", Main.textoStack);
            JOptionPane.showMessageDialog(null, "Não há elementos na pilha.");
            Main.textPane.getStyledDocument().setCharacterAttributes(0, Main.textoStack.length(), Main.defaultText, true);

        } else {
            Main.highlightsText("  } senao   {\n", Main.textoStack);
            Main.highlightsText("    int top = pilha[tamanho - 1];\n", Main.textoStack);
            Main.highlightsText("  retorna top;\n", Main.textoStack);
            JOptionPane.showMessageDialog(null, "O elemento do topo da pilha é: " + Main.vetorNumeros[Main.stackSize - 1].numero);
            Main.textPane.getStyledDocument().setCharacterAttributes(0, Main.textoStack.length(), Main.defaultText, true);
            Main.textPane2.setText("tamanho = " + Main.stackSize + "\ncapacidade = " + (Main.capacity));
        }
    }

    public static void showElements() {

        if (Main.stackSize == 0) {

            JOptionPane.showMessageDialog(null, "Não há elementos na pilha.");

        } else {


            String numeros = "{ ";

            for (int i = 0; i < Main.stackSize; i++) {
                numeros += Main.vetorNumeros[i].numero + " ";
            }
            numeros += "}";

            JOptionPane.showMessageDialog(null, "Elementos: " + numeros);

        }

    }

    public void callStackButtons() {


        JFrame frame = new JFrame("Stack Actions");
//        frame.setLayout(new FlowLayout());
        
        
        JPanel stackButtonsPanel = new JPanel(new GridLayout(3, 0));

        JButton addButton = new JButton("Push");
        JButton removeButton = new JButton("Pop");
        JButton lastElementButton = new JButton("Top");
        JButton showElementsButton = new JButton("Stack Elements");

        addButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                Thread t = new ThreadAuxiliary(stackThread, 1);
                t.start();
            }
        });

        removeButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                Thread t = new ThreadAuxiliary(stackThread, 2);
                t.start();
            }
        });

        lastElementButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                Thread t = new ThreadAuxiliary(stackThread, 3);
                t.start();
            }
        });

        showElementsButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                showElements();
            }
        });

        JLabel exitLabel = new JLabel("Para finalizar a execução da pilha, feche esta janela");
        JTextArea exitText = new JTextArea("Para finalizar a execução da pilha, feche esta janela");
        exitText.setEditable(false);
        exitText.setLineWrap(true);
        exitText.setAutoscrolls(true);
        stackButtonsPanel.add(addButton);
        stackButtonsPanel.add(removeButton);
        stackButtonsPanel.add(lastElementButton);
        stackButtonsPanel.setPreferredSize(new Dimension(80, 140));
//        stackButtonsPanel.add(showElementsButton);
        frame.add(stackButtonsPanel);
        
//        textPane = new JTextPane();
//        textPane.setText(Main.textoStack);
//        
//        frame.add(textPane, BorderLayout.CENTER);
        frame.setBounds(415, 64, 300, 140);

        frame.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                for (int i = 0; i < Main.stackSize; i++) {
                    Main.destroySphereStack(i);
                }
                Main.stackSize = 0;
                Main.isRunning = false;
                Main.clearTexts();
                Main.frame.setEnabled(true);

            }
        });

        frame.setResizable(false);
        frame.setVisible(true);
        Main.textPane.setText(Main.textoStack);
        
    }
}
